package com.ins.secure.interceptor;

import com.ins.common.anno.NoLogin;
import com.ins.common.enums.ErrEnum;
import com.ins.common.utils.Json;
import com.ins.common.utils.Result;
import com.ins.common.utils.SecureUser;
import com.ins.common.utils.TokenUtils;
import com.ins.model.entity.AppUser;
import com.ins.secure.cache.TokenStoreCache;
import com.mybatisflex.processor.util.StrUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;

/**
 * AuthInterceptor
 *
 * @author ins
 * @version 1.0
 * @since 2024/5/13
 */
@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Resource
    @Lazy
    private TokenStoreCache tokenStoreCache;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // OPTIONS请求直接return
        if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
            response.setStatus(HttpStatus.NO_CONTENT.value());
            return false;
        }

        boolean isHandler = handler instanceof HandlerMethod;
        if (!isHandler) {
            return true;
        }

        //不需要登录
        NoLogin noLogin = ((HandlerMethod) handler).getMethodAnnotation(NoLogin.class);
        // 无token 无需登录
        if (null != noLogin) {
            return true;
        }
        String accessToken = TokenUtils.getAccessToken(request);
        if (StrUtil.isBlank(accessToken)) {
            this.outputResult(response, Result.err(ErrEnum.RE_LOGIN));
            return false;
        }

        AppUser user = tokenStoreCache.getUser(accessToken);
        if (user == null) {
            return false;
        }

        SecureUser.set(user);
        return true;
    }

    /**
     * 错误输出
     *
     * @param response 响应
     * @param r        响应结果
     * @throws IOException io异常
     */
    private void outputResult(HttpServletResponse response, Result<String> r) throws IOException {
        String msg = Json.toStr(r);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(msg);
        response.flushBuffer();
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        SecureUser.remove();
    }
}
